﻿using System;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Reflection;
using System.Text;
using MicropleSoft.WmsServiceLibrary.Data;
using MicropleSoft.WmsServiceLibrary.Domain.Base;
using MicropleSoft.WmsServiceLibrary.Exceptions;
using MicropleSoft.WmsServiceLibrary.Security;

namespace MicropleSoft.WmsServiceLibrary.Base
{
    public abstract class BaseService
    {
        public const string CreatedByFieldName = "CREATED_BY";
        public const string CreatedDateFieldName = "CREATED_DATE";
        public const string UpdatedByFieldName = "UPDATED_BY";
        public const string UpdatedDateFieldName = "UPDATED_DATE";
        protected static readonly List<String> CreateOrUpdateRecordPropertyList = new List<String>() { "CreatedBy", "CreatedDate", "UpdatedBy", "UpdatedDate" };
        protected static readonly List<String> CreateRecordPropertyList = new List<String>() { "CreatedBy", "CreatedDate", };
        protected void DomainObject2EntityObject(IBaseDomainEntity domainEntity,EntityObject entityObject)
        {
            PropertyInfo[] propertyInfos = domainEntity.GetType().GetProperties();
            foreach (var propertyInfo in propertyInfos)
            {
                object[] attributes = null;
                if((attributes =propertyInfo.GetCustomAttributes(typeof (DataFieldNameAttribute), false)).Count()>0)
                {
                    string fieldName = ((DataFieldNameAttribute) attributes[0]).FieldName;
                    PropertyInfo propertyInfoEntityObject = entityObject.GetType().GetProperty(fieldName);
                    propertyInfoEntityObject.SetValue(entityObject, propertyInfo.GetValue(domainEntity,null),null);
                }
            }

            PropertyInfo propertyInfoEntityObject2 = null;
            if (domainEntity.DomainObjectState == DomainEntityState.Added)
            {
                propertyInfoEntityObject2 = entityObject.GetType().GetProperty(CreatedByFieldName);
                if (propertyInfoEntityObject2 != null)
                {
                    propertyInfoEntityObject2.SetValue(entityObject, this.GetUserId(), null);
                }

                propertyInfoEntityObject2 = entityObject.GetType().GetProperty(CreatedDateFieldName);
                if (propertyInfoEntityObject2 != null)
                {
                    propertyInfoEntityObject2.SetValue(entityObject, this.GetNow(), null);
                }
            }

            propertyInfoEntityObject2 = entityObject.GetType().GetProperty(UpdatedByFieldName);
            if (propertyInfoEntityObject2 != null)
            {
                propertyInfoEntityObject2.SetValue(entityObject, this.GetUserId(), null);
            }

            propertyInfoEntityObject2 = entityObject.GetType().GetProperty(UpdatedDateFieldName);
            if (propertyInfoEntityObject2 != null)
            {
                propertyInfoEntityObject2.SetValue(entityObject, this.GetNow(), null);
            }
        }


        protected void DomainObject2EntityObject(IBaseDomainEntity domainEntity, EntityObject entityObject, PropertyInfo[] propertyInfos, String[] entityKeyList)
        {
            foreach (var propertyInfo in propertyInfos)
            {
                if (propertyInfo.PropertyType == typeof(DomainEntityState)
                    || CreateOrUpdateRecordPropertyList.Contains(propertyInfo.Name))
                {
                    continue;
                }

                object[] attributes = null;
                if ((attributes = propertyInfo.GetCustomAttributes(typeof(DataFieldNameAttribute), false)).Count() > 0)
                {
                    string fieldName = ((DataFieldNameAttribute)attributes[0]).FieldName;
                    PropertyInfo propertyInfoEntityObject = entityObject.GetType().GetProperty(fieldName);
                    propertyInfoEntityObject.SetValue(entityObject, propertyInfo.GetValue(domainEntity, null), null);
                }
            }

            PropertyInfo propertyInfoEntityObject2 = null;
            if (domainEntity.DomainObjectState == DomainEntityState.Added)
            {
                propertyInfoEntityObject2 = entityObject.GetType().GetProperty(CreatedByFieldName);
                if (propertyInfoEntityObject2 != null)
                {
                    propertyInfoEntityObject2.SetValue(entityObject, this.GetUserId(), null);
                }

                propertyInfoEntityObject2 = entityObject.GetType().GetProperty(CreatedDateFieldName);
                if (propertyInfoEntityObject2 != null)
                {
                    propertyInfoEntityObject2.SetValue(entityObject, this.GetNow(), null);
                }
            }

            propertyInfoEntityObject2 = entityObject.GetType().GetProperty(UpdatedByFieldName);
            if (propertyInfoEntityObject2 != null)
            {
                propertyInfoEntityObject2.SetValue(entityObject, this.GetUserId(), null);
            }

            propertyInfoEntityObject2 = entityObject.GetType().GetProperty(UpdatedDateFieldName);
            if (propertyInfoEntityObject2 != null)
            {
                propertyInfoEntityObject2.SetValue(entityObject, this.GetNow(), null);
            }
        }

        protected void EntityObject2DomainObject(EntityObject entityObject, IBaseDomainEntity domainEntity)
        {
            PropertyInfo[] propertyInfos = domainEntity.GetType().GetProperties();
            foreach (var propertyInfo in propertyInfos)
            {
                object[] attributes = null;
                if ((attributes = propertyInfo.GetCustomAttributes(typeof(DataFieldNameAttribute), false)).Count() > 0)
                {
                    string fieldName = ((DataFieldNameAttribute)attributes[0]).FieldName;
                    PropertyInfo propertyInfoEntityObject = entityObject.GetType().GetProperty(fieldName);
                    propertyInfo.SetValue(domainEntity, propertyInfoEntityObject.GetValue(entityObject,null),null);
                }
            }
        }

        protected string GetUserId()
        {
            return AuthenticationFactory.GetAuthentication().GetCurrentUserId();
        }

        protected string GetUserName()
        {
            return AuthenticationFactory.GetAuthentication().GetCurrentUserName();
        }

        protected DateTime GetNow()
        {
            return DateTime.Now;
        }
    }
}
